package edu.gmu.projects.fireresponder.notificationhandler;

import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.ArrayList;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Binder;
import android.os.IBinder;
import android.os.Vibrator;
import android.preference.PreferenceManager;
import android.util.Log;
import android.widget.Toast;
import edu.gmu.projects.fireresponder.R;
import edu.gmu.projects.fireresponder.beacon.BeaconService;
import edu.gmu.projects.fireresponder.environment.Asset;
import edu.gmu.projects.fireresponder.environment.Path;
import edu.gmu.projects.fireresponder.environment.Safespot;
import edu.gmu.projects.fireresponder.fusionengine.FusionEngine;
import edu.gmu.projects.fireresponder.gui.NotificationDialogActivity;
import edu.gmu.projects.fireresponder.gui.NotificationsDbAdapter;
import edu.gmu.projects.fireresponder.gui.NotificationsList;
import edu.gmu.projects.fireresponder.gui.SituationMapPreferences;
import edu.gmu.projects.fireresponder.relevancyengine.RelevanceEngine;
import edu.gmu.projects.fireresponder.relevancyengine.RelevanceEngineService;

public class NotificationHandlerService extends Service implements
		INotificationHandlerListener {
	private ArrayList<Integer> activeNotes = new ArrayList<Integer>();
	private NotificationManager notificationManager;
	private NotificationHandler notificationHandler;
	private NotificationsDbAdapter mDbHelper;

	public NotificationHandler getNotificationHandler() {
		if (notificationHandler == null) {
			notificationHandler = new NotificationHandler();
		}

		return notificationHandler;
	}

	private final IBinder mBinder = new LocalBinder();

	public class LocalBinder extends Binder {
		public NotificationHandlerService getService() {
			return NotificationHandlerService.this;
		}
	}

	@Override
	public IBinder onBind(Intent intent) {
		return mBinder;
	}

	@Override
	public void onCreate() {
		super.onCreate();

		bindService(new Intent(this, RelevanceEngineService.class),
				relevanceServiceConnection, BIND_AUTO_CREATE);
		bindService(new Intent(this, BeaconService.class), beaconConnection,
				BIND_AUTO_CREATE);

		mDbHelper = new NotificationsDbAdapter(this);
		mDbHelper.open();

		notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

		getNotificationHandler().addNotificationListener(
				NotificationHandlerService.this);

		Log.i("NotificationHandlerService",
				"Created NotificationHandlerService service");
	}

	@Override
	public void onDestroy() {
		mDbHelper.close();

		for (Integer i : activeNotes) {
			notificationManager.cancel(i);
		}

		getNotificationHandler().removeNotificationListener(
				NotificationHandlerService.this);

		unbindService(relevanceServiceConnection);
		unbindService(beaconConnection);

		super.onDestroy();
		Log.i("NotificationHandlerService",
				"Destroyed NotificationHandlerService service");
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		return START_STICKY;
	}

	private RelevanceEngineService relevanceService;

	private ServiceConnection relevanceServiceConnection = new ServiceConnection() {
		public void onServiceConnected(ComponentName className, IBinder service) {
			relevanceService = ((RelevanceEngineService.LocalBinder) service)
					.getService();
			relevanceService.getRelevanceEngine().addListener(
					getNotificationHandler());

			Log.i("NotificationHandlerService",
					"Connected to RelevanceEngineService");
		}

		public void onServiceDisconnected(ComponentName arg0) {
			relevanceService.getRelevanceEngine().removeListener(
					getNotificationHandler());
			relevanceService = null;

			Log.i("NotificationHandlerService",
					"Disconnected from RelevanceEngineService");
		}
	};

	private BeaconService beaconService;

	private ServiceConnection beaconConnection = new ServiceConnection() {
		public void onServiceConnected(ComponentName className, IBinder service) {
			beaconService = ((BeaconService.LocalBinder) service).getService();
			beaconService
					.addResponderStatusListener(NotificationHandlerService.this);

			Log.i("SituationMap", "Connected to BeaconService");
		}

		public void onServiceDisconnected(ComponentName arg0) {
			beaconService
					.removeResponderStatusListener(NotificationHandlerService.this);
			beaconService = null;

			Log.i("SituationMap", "Disconnected from BeaconService");
		}
	};

	public void addFireNotificationToDatabase(Asset asset) {
		Date date = new Date(System.currentTimeMillis());
		SimpleDateFormat formater = new SimpleDateFormat("hh:mm a, MM/dd/yyyy");

		String title = "";

		if (asset instanceof Path || asset instanceof Safespot) {
			title = String.format("%s %s\n%s",
					asset.getClass().getSimpleName(), asset.getId(), formater
							.format(date));
		} else {
			title = String.format("%s\n%s", asset.getId(), formater
					.format(date));
		}

		String bodyTitle = "Fire at " + asset.getId();

		String fireText = String
				.format("Fire Probability: %s", FusionEngine
						.getProbabilityCategoryText(asset
								.getProbabilityOfFire() * 100));

		String peopleText = String.format("People Probability: %s",
				FusionEngine.getProbabilityCategoryText(asset
						.getProbabilityOfPresence() * 100));

		String missionText = String.format("Mission Relevance: %s",
				RelevanceEngine
						.getRelevanceScaleText(asset.getRelevanceValue()));

		String body = String.format("%s\n\n%s\n%s\n%s", bodyTitle, fireText,
				peopleText, missionText);

		mDbHelper.createNote(title, body);
	}

	public void addStatusBarNotification(int id, CharSequence title,
			CharSequence body) {
		int icon = R.drawable.stat_emergency_alert;
		long when = System.currentTimeMillis();

		Notification notification = new Notification(icon, title, when);

		PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
				new Intent(this, NotificationsList.class), 0);

		notification.setLatestEventInfo(this, title, body, contentIntent);

		notificationManager.notify(id, notification);
		activeNotes.add(new Integer(id));
	}

	public void showToastMessage(String message) {
		Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT)
				.show();
	}

	public void showDialogAlert(String message) {
		Intent intent = new Intent(getApplicationContext(),
				NotificationDialogActivity.class);

		intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		intent.putExtra(NotificationDialogActivity.DIALOG_MESSAGE, message);

		startActivity(intent);
	}

	public void ringRingerNotification() {
		// TODO Auto-generated method stub

	}

	public void vibratePhoneNotification() {
		boolean useVibPref = PreferenceManager.getDefaultSharedPreferences(
				getApplicationContext()).getBoolean(
				SituationMapPreferences.USE_VIB_PREF, false);

		if (useVibPref) {
			Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);

			if (v != null) {
				v.vibrate(500);
			}
		}
	}
}